﻿

#include <QtWidgets/QApplication>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DRender/QCamera>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QPointLight>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QAttribute>

#include <QVector3D>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QWidget>
#include <QTimer>
#include <QLabel>
#include <QSlider>

//#include "main.moc"


#define M_PI (3.1415926)

class MaterialPalletizingSystem : public QWidget {
	Q_OBJECT

public:
	MaterialPalletizingSystem(QWidget* parent = nullptr)
		: QWidget(parent) {
		// 初始化3D场景
		setup3DScene();

		// 创建控制面板
		setupControlPanel();

		// 设置主布局
		QHBoxLayout* mainLayout = new QHBoxLayout;
		mainLayout->addWidget(container, 4);
		mainLayout->addLayout(controlLayout, 1);
		setLayout(mainLayout);

		setWindowTitle("物料拆码垛3D模拟系统");
		resize(1200, 800);
	}

	// 添加托盘接口
	void addPallet(const QVector3D& size, const QVector3D& position) {
		QVector3D pos = position;
		pos[2] -= (size[2]) / 2;
		Qt3DCore::QEntity* pallet = createCuboid(size, position, QColor(139, 69, 19));
		pallet->setObjectName("Pallet");
		pallets.append(pallet);
	}

	// 添加物料接口
	void addMaterial(const QVector3D& size, const QVector3D& position) {
		Qt3DCore::QEntity* material = createCuboid(size, position, QColor(70, 130, 180));
		material->setObjectName("Material");
		materials.append(material);
	}

	// 创建夹具
	void createGripper(const QVector3D& size) {
		if (gripper) {
			delete gripper;
		}

		gripper = createCuboid(size, QVector3D(0, 0, 0), QColor(220, 20, 60));
		gripper->setObjectName("Gripper");
		gripperTransform = gripper->componentsOfType<Qt3DCore::QTransform>().first();
	}

	// 移动夹具到指定位置
	void moveGripper(const QVector3D& position) {
		if (!gripperTransform) return;

		QPropertyAnimation* anim = new QPropertyAnimation(gripperTransform, "translation");
		anim->setDuration(1000);
		anim->setStartValue(gripperTransform->translation());
		anim->setEndValue(position);
		anim->start(QAbstractAnimation::DeleteWhenStopped);
	}

	// 抓取物料
	void gripMaterial(Qt3DCore::QEntity* material) {
		if (!material || !gripper) return;

		// 将物料添加为夹具的子实体
		material->setParent(gripper);

		// 调整物料位置到夹具下方
		Qt3DCore::QTransform* materialTransform = material->componentsOfType<Qt3DCore::QTransform>().first();
		materialTransform->setTranslation(QVector3D(0, 0, -gripperSize.z() / 2 - materialSize.z() / 2));

		grippedMaterial = material;
	}

	// 释放物料
	void releaseMaterial() {
		if (!grippedMaterial) return;

		// 从夹具中移除物料
		grippedMaterial->setParent(rootEntity);

		// 获取当前物料位置
		Qt3DCore::QTransform* materialTransform = grippedMaterial->componentsOfType<Qt3DCore::QTransform>().first();
		QVector3D currentPos = gripperTransform->translation() + materialTransform->translation();

		// 更新物料位置
		materialTransform->setTranslation(currentPos);

		grippedMaterial = nullptr;
	}

	// 执行拆码垛循环
	void executePalletizingCycle() {
		if (materials.isEmpty()) return;

		// 获取第一个物料
		Qt3DCore::QEntity* material = materials.first();
		Qt3DCore::QTransform* materialTransform = material->componentsOfType<Qt3DCore::QTransform>().first();
		QVector3D materialPos = materialTransform->translation();

		// 获取托盘位置
		QVector3D palletPos = pallets.isEmpty() ? QVector3D(0, -1000, 0) :
			pallets.first()->componentsOfType<Qt3DCore::QTransform>().first()->translation();

		// 1. 夹具移动到物料上方
		moveGripper(materialPos + QVector3D(0, 0, 200));

		// 2. 下降抓取物料
		QTimer::singleShot(1200, this, [=]() {
			moveGripper(materialPos + QVector3D(0, 0, 100));

			QTimer::singleShot(1200, this, [=]() {
				gripMaterial(material);

				// 3. 提升物料
				QTimer::singleShot(500, this, [=]() {
					moveGripper(materialPos + QVector3D(0, 0, 200));

					// 4. 移动到托盘上方
					QTimer::singleShot(1200, this, [=]() {
						moveGripper(palletPos + QVector3D(0, 0, 200));

						// 5. 下降到托盘位置
						QTimer::singleShot(1200, this, [=]() {
							moveGripper(palletPos + QVector3D(0, 0, materialSize.z() / 2 + 10));

							// 6. 释放物料
							QTimer::singleShot(1200, this, [=]() {
								releaseMaterial();

								// 7. 提升夹具
								QTimer::singleShot(500, this, [=]() {
									moveGripper(palletPos + QVector3D(0, 0, 200));

									// 8. 返回原点
									QTimer::singleShot(1200, this, [=]() {
										moveGripper(QVector3D(0, 0, 0));

										// 移除已放置的物料
										materials.removeFirst();
										//material->deleteLater();
										});
									});
								});
							});
						});
					});
				});
			});
	}

private:
	void setup3DScene() {
		// 创建3D窗口
		view = new Qt3DExtras::Qt3DWindow();
		container = QWidget::createWindowContainer(view);

		// 创建根实体
		rootEntity = new Qt3DCore::QEntity();

		// 设置相机
		camera = view->camera();
		camera->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 10000.0f);
		camera->setPosition(QVector3D(0, 3000, 3000));
		camera->setViewCenter(QVector3D(0, 0, 0));

		// 添加相机控制器
		Qt3DExtras::QOrbitCameraController* camController =
			new Qt3DExtras::QOrbitCameraController(rootEntity);
		camController->setCamera(camera);

		// 添加灯光
		Qt3DCore::QEntity* lightEntity = new Qt3DCore::QEntity(rootEntity);
		Qt3DRender::QPointLight* pointLight = new Qt3DRender::QPointLight(lightEntity);
		pointLight->setColor(Qt::white);
		pointLight->setIntensity(1.0f);
		lightEntity->addComponent(pointLight);
		Qt3DCore::QTransform* lightTransform = new Qt3DCore::QTransform();
		lightTransform->setTranslation(camera->position());
		lightEntity->addComponent(lightTransform);

		// 创建坐标系
		createCoordinateSystem();

		// 设置场景
		view->setRootEntity(rootEntity);
	}

	void createCoordinateSystem() {
		// 创建X轴（红色）
		createLine(QVector3D(-3000, 0, 0), QVector3D(3000, 0, 0), QColor(255, 0, 0));

		// 创建Y轴（绿色）
		createLine(QVector3D(0, -3000, 0), QVector3D(0, 3000, 0), QColor(0, 255, 0));

		// 创建Z轴（蓝色）
		createLine(QVector3D(0, 0, -1000), QVector3D(0, 0, 2000), QColor(0, 0, 255));

		// 创建网格平面
		createGridPlane();
	}

	void createLine(const QVector3D& start, const QVector3D& end, const QColor& color) {
		Qt3DCore::QEntity* lineEntity = new Qt3DCore::QEntity(rootEntity);

		Qt3DRender::QGeometryRenderer* lineRenderer = new Qt3DRender::QGeometryRenderer;
		Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(lineRenderer);

		QByteArray vertexData;
		vertexData.resize(2 * 3 * sizeof(float));
		float* vPtr = reinterpret_cast<float*>(vertexData.data());

		*vPtr++ = start.x(); *vPtr++ = start.y(); *vPtr++ = start.z();
		*vPtr++ = end.x();   *vPtr++ = end.y();   *vPtr++ = end.z();

		Qt3DRender::QBuffer* vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry);
		vertexBuffer->setData(vertexData);

		Qt3DRender::QAttribute* positionAttribute = new Qt3DRender::QAttribute();
		positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
		positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
		positionAttribute->setVertexSize(3);
		positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
		positionAttribute->setBuffer(vertexBuffer);
		positionAttribute->setByteStride(3 * sizeof(float));
		positionAttribute->setCount(2);
		geometry->addAttribute(positionAttribute);

		lineRenderer->setGeometry(geometry);
		lineRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);

		Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial;
		material->setAmbient(color);

		lineEntity->addComponent(lineRenderer);
		lineEntity->addComponent(material);
	}

	void createGridPlane() {
		const int gridSize = 3000;
		const int step = 200;

		for (int i = -gridSize; i <= gridSize; i += step) {
			createLine(QVector3D(i, -gridSize, -1000), QVector3D(i, gridSize, -1000), QColor(100, 100, 100));
			createLine(QVector3D(-gridSize, i, -1000), QVector3D(gridSize, i, -1000), QColor(100, 100, 100));
		}
	}

	Qt3DCore::QEntity* createCuboid(const QVector3D& size, const QVector3D& position, const QColor& color) {
		Qt3DCore::QEntity* cuboid = new Qt3DCore::QEntity(rootEntity);

		// 创建立方体网格
		Qt3DExtras::QCuboidMesh* cuboidMesh = new Qt3DExtras::QCuboidMesh;
		cuboidMesh->setXExtent(size.x());
		cuboidMesh->setYExtent(size.y());
		cuboidMesh->setZExtent(size.z());

		// 创建材质
		Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial;
		material->setDiffuse(color);
		material->setShininess(50.0f);

		// 创建变换组件
		Qt3DCore::QTransform* transform = new Qt3DCore::QTransform;
		transform->setTranslation(position);

		// 添加组件到实体
		cuboid->addComponent(cuboidMesh);
		cuboid->addComponent(material);
		cuboid->addComponent(transform);

		return cuboid;
	}

	void setupControlPanel() {
		controlLayout = new QVBoxLayout;

		// 标题
		QLabel* title = new QLabel("物料拆码垛控制系统");
		title->setStyleSheet("font-size: 18px; font-weight: bold;");
		controlLayout->addWidget(title);

		// 添加托盘按钮
		QPushButton* addPalletBtn = new QPushButton("添加托盘");
		controlLayout->addWidget(addPalletBtn);
		connect(addPalletBtn, &QPushButton::clicked, this, [=]() {
			addPallet(QVector3D(1000, 1200, 150), QVector3D(0, -1500, -750));
			});

		// 添加物料按钮
		QPushButton* addMaterialBtn = new QPushButton("添加物料");
		controlLayout->addWidget(addMaterialBtn);
		connect(addMaterialBtn, &QPushButton::clicked, this, [=]() {
			materialSize = QVector3D(300, 400, 200);
			addMaterial(materialSize, QVector3D(0, 1500, 100));
			});

		// 创建夹具按钮
		QPushButton* createGripperBtn = new QPushButton("创建夹具");
		controlLayout->addWidget(createGripperBtn);
		connect(createGripperBtn, &QPushButton::clicked, this, [=]() {
			gripperSize = QVector3D(400, 500, 10);
			createGripper(gripperSize);
			});

		// 执行循环按钮
		QPushButton* executeBtn = new QPushButton("执行拆码垛循环");
		executeBtn->setStyleSheet("background-color: #4CAF50; color: white; font-weight: bold;");
		controlLayout->addWidget(executeBtn);
		connect(executeBtn, &QPushButton::clicked, this, &MaterialPalletizingSystem::executePalletizingCycle);

		// 移动夹具到原点
		QPushButton* homeBtn = new QPushButton("夹具回原点");
		controlLayout->addWidget(homeBtn);
		connect(homeBtn, &QPushButton::clicked, this, [=]() {
			moveGripper(QVector3D(0, 0, 0));
			});

		// 相机控制
		QLabel* cameraLabel = new QLabel("相机视角控制");
		controlLayout->addWidget(cameraLabel);

		QSlider* cameraSlider = new QSlider(Qt::Horizontal);
		cameraSlider->setRange(0, 360);
		cameraSlider->setValue(145);
		controlLayout->addWidget(cameraSlider);
		connect(cameraSlider, &QSlider::valueChanged, this, [=](int value) {
			float angle = value * M_PI / 180.0f;
			float distance = 6000;
			QVector3D pos(distance * sin(angle), distance * cos(angle), 4000);
			camera->setPosition(pos);
			});

		// 状态信息
		QLabel* statusLabel = new QLabel("系统状态: 就绪");
		statusLabel->setStyleSheet("font-weight: bold; margin-top: 20px;");
		controlLayout->addWidget(statusLabel);

		// 填充空白
		controlLayout->addStretch();
	}

private:
	// 3D场景组件
	Qt3DExtras::Qt3DWindow* view;
	QWidget* container;
	Qt3DCore::QEntity* rootEntity;
	Qt3DRender::QCamera* camera;

	// 控制面板
	QVBoxLayout* controlLayout;

	// 系统实体
	QList<Qt3DCore::QEntity*> pallets;
	QList<Qt3DCore::QEntity*> materials;
	Qt3DCore::QEntity* gripper = nullptr;
	Qt3DCore::QTransform* gripperTransform = nullptr;
	Qt3DCore::QEntity* grippedMaterial = nullptr;

	// 尺寸参数
	QVector3D materialSize = QVector3D(300, 400, 200);
	QVector3D gripperSize = QVector3D(400, 500, 100);
};

int main(int argc, char* argv[]) {
	QApplication app(argc, argv);

	MaterialPalletizingSystem system;
	system.show();

	return app.exec();
}

#include "mian.moc"
